home *** CD-ROM | disk | FTP | other *** search
- /*
- FlipperUtils.c
- written in Think C 4.0 by Chris Sanchez
- Copyright ©1990 Chris Sanchez, All Rights Reserved
- */
-
- #include "PixelFlipper.h"
- #include "FlipperUtils.h"
-
- /**********************************************************************************************
- Private Routines for the Utilities
- **********************************************************************************************/
- static Boolean WritePref(HParmBlkPtr h, PREFPtr p)
- /* -> h, p. h is the parameter block that contains the information about the file
- that we are going to save the preferences to. p is the preferences that are to be saved.
- <- Boolean. If the operation was successful, then it will return TRUE, else
- it will report the error and return false.
- */
- {
- h->ioParam.ioPosOffset = 0;
- h->ioParam.ioBuffer = p;
- if (!CheckError(PBWrite(h, FALSE), noErr, kCreating)) return FALSE; /* space has been allocated */
- if (PBGetEOF(h, FALSE) != noErr) return FALSE; /* get the eof */
- if (PBSetEOF(h, FALSE) != noErr) return FALSE; /* set the eof */
- FlushVol( NIL, h->fileParam.ioVRefNum);
- return TRUE;
- }
-
- static Boolean Find1File(short *theRefNum,long *theDir, char *fileName, Boolean directory)
- /* -> theRefNum, theDir, fileName, directory. directory specifies whether the routine is
- searching for a directory (folder) or a file. If directory is TRUE, then theRefNum
- is a working directory number and theDir is NUL upon entry.
- Otherwise, theRefNum is a volume reference number and theDir is a directory ID.
- <- If we were searching for a directory, then theDir will contain the directory ID
- of the requested directory and the function will return a TRUE as the result of the search.
- Otherwise, theDir will contain the file's parent directory ID. Similarly, TRUE will
- be returned as the function result.
- If the file wasn't found, then the function will return FALSE.
- */
- { short count=1;
- CInfoPBRec ciPB;
- char fname[33];
- Str255 altStr;
-
- ClearPointer(&ciPB, sizeof(ciPB));
- ciPB.dirInfo.ioNamePtr = fname;
- while (TRUE){ /* loop until fnfErr */
- ciPB.dirInfo.ioFDirIndex = count++;
- ciPB.dirInfo.ioVRefNum = *theRefNum;
- if (!directory)
- ciPB.hFileInfo.ioDirID = *theDir;
- else
- ciPB.dirInfo.ioDrDirID = NIL;
- if (PBGetCatInfo(&ciPB,FALSE) != noErr) /* if err return (reached end of dir) */
- return FALSE;
- if (IUCompString(fname, fileName) == 0){ /* is this the file we wanted */
- if (ciPB.dirInfo.ioFlAttrib & 0x10){ /* is it a directory */
- *theDir = ciPB.dirInfo.ioDrDirID; /* return its directory id */
- if (!directory) /* is this a file rather than a directory */
- return Find1File(theRefNum, theDir, fileName, directory); /* then we found the file in this dir */
- else
- return TRUE;
- }else /* it is a file */
- if(directory){ /* a file was found with the same name as the directory we are trying to find */
- GetIndString(altStr, kStrPixel, kAltDesig);
- pStrcat(fileName, altStr);
- return Find1File(theRefNum, theDir, fileName, directory); /* then we found the file in this dir */
- }else
- *theDir = ciPB.hFileInfo.ioFlParID; /* return its parents directory id */
- return TRUE;
- }
- }
- }
- /**********************************************************************************************
- Public Routines for PixelFlipper INIT & cdev
- **********************************************************************************************/
- Boolean Get_Set_Prefs(PREFRec *p, short theVRef, Boolean writing)
- /* -> p, theVRef. p is the preferences that are to be gotten from the preferences file.
- theVRef is the working directory reference number that the INIT is in.
- <- Boolean. If the operation was successful, then it will return TRUE, else
- it will report the error and return false.
- */
- { HParamBlockRec h;
- short prefVol = theVRef;
- OSErr err;
- Str255 prefName, prefDirName, tempStr;
- char found = FALSE;
- long prefDirID;
- StringHandle s1;
- VersRecHdl v;
-
- GetIndString(prefName, kStrPixel, kPrefFile);
- if (s1 = GetString(kStrFolder)){ /* this is the prefs dirID string */
- pStrcpy(prefDirName, *s1);
- StringToNum(prefDirName, &prefDirID);
- ReleaseResource(s1);
- if (GetVol(NIL, &prefVol) == noErr){ /* if this is the dirID, then we have to also get the volRefNum */
- ClearPointer(&h, sizeof(HParamBlockRec)); /* No errors, then open the file. */
- h.ioParam.ioNamePtr = prefName;
- h.ioParam.ioVRefNum = prefVol;
- h.fileParam.ioDirID = prefDirID;
- h.ioParam.ioPermssn = fsRdWrPerm;
- if (PBHOpen(&h, FALSE) == noErr)
- found = TRUE;
- else
- prefVol = theVRef; /* Reset the prefVol to the working dirID */
- }else
- prefVol = theVRef; /* same thing here */
- }
-
- if(!found){ /* The dirID wasn't found */
- GetIndString(prefDirName, kStrPixel, kPrefDir);
- if (!Find1File(&prefVol, &prefDirID, (char *)prefDirName, TRUE)) /* look for the preferences folder */
- if (DirCreate(theVRef, NIL, prefDirName, &prefDirID) != noErr)
- return FALSE; /* bow out because we weren't able to create a preferences folder */
-
- /* we have a preferences folder at this point */
- if (!Find1File(&prefVol, &prefDirID, (char *)prefName, FALSE)) /* look for the PixelFlipper preferences file */
- if (HCreate(prefVol, prefDirID, prefName, kOurCreat, kPrefType) != noErr)
- return FALSE; /* bow out because we weren't able to create a preferences file */
- ClearPointer(&h, sizeof(HParamBlockRec));
- h.ioParam.ioNamePtr = prefName;
- h.ioParam.ioVRefNum = prefVol;
- h.fileParam.ioDirID = prefDirID;
- h.ioParam.ioPermssn = fsRdWrPerm;
- if (!CheckError(PBHOpen(&h, FALSE), opWrErr, kOpeningPr)){
- return FALSE;
- }
- }
- /* no errors opening so continue */
- h.ioParam.ioReqCount = sizeof(PREFRec);
- h.ioParam.ioBuffer = p; /* this is what we return the data in */
- h.ioParam.ioPosMode = fsFromStart;
- h.ioParam.ioPosOffset = 0;
-
- if (writing){ /* we are writing out the preferences out */
- if (!WritePref(&h, p)){ /* we weren't able to read the proper number of bytes in */
- PBClose(&h, FALSE);
- return FALSE;
- }
- }else{ /* we are reading in the preferences */
- err = PBRead(&h, FALSE);
- if ((err != eofErr) && (err != noErr)){
- PBClose(&h, FALSE);
- return FALSE;
- }
- }
- /* no errors reading so continue */
- if ((h.ioParam.ioActCount != sizeof(PREFRec)) && !writing){ /* wrong number of bytes read / written */;
- p->isPerm = FALSE;
- p->showIcon = TRUE;
- p->hotKey = optionKey + shiftKey;
- if(v = (VersRecHdl)Get1Resource('vers', 1)){
- pStrcpy(p->ver, (**v).message);
- ReleaseResource(v);
- }else
- pStrcpy(p->ver, "\punknown");
- p->active = TRUE;
- if (!WritePref(&h, p)){ /* we weren't able to read the proper number of bytes in */
- PBClose(&h, FALSE);
- return FALSE;
- }
- }
- if (!CheckError(PBClose(&h, FALSE), noErr, kSaving)) return FALSE;
-
- if (!writing)
- if (s1 = Get1Resource('STR ', kStrFolder)){ /* this is the directory ID of the prefs file */
- NumToString(prefDirID, tempStr);
- if (IUCompString(*s1, tempStr) != 0){
- SetString(s1, tempStr);
- ChangedResource(s1);
- UpdateResFile(CurResFile());
- }
- ReleaseResource(s1);
- }else{ /* we couldn't find the 'STR ' resource */
- NumToString(prefDirID, tempStr);
- if (s1 = NewString(tempStr)){
- AddResource(s1, 'STR ', kStrFolder, nullStr);
- UpdateResFile(CurResFile());
- DisposHandle(s1);
- }/*else -- we can't use the 'STR ' resource for some reason, and we will have to search for the file each t1me */
- }
-
- return TRUE; /* viola, no problems */
- }
-
- void PosWindow(WindowPtr theWind, GDHandle gDev)
- /* -> theWind, gDev, The wind is the window we want to position. gDev is
- the graphics device we want to position the window in. We don't want to
- position the window across different graphics devices.
- <- nothing is returned.
- */
- { short h,v;
-
- h = (((**gDev).gdRect.right - (**gDev).gdRect.left)/2) - ((theWind->portRect.right - theWind->portRect.left)/2);
- v = (((**gDev).gdRect.bottom - (**gDev).gdRect.top)/2) - ((theWind->portRect.bottom - theWind->portRect.top)/2);
- MoveWindow(theWind, h, v,TRUE);
- ShowWindow(theWind);
- SelectWindow(theWind);
- SetPort(theWind);
- }
-
- void pStrcat(unsigned char *dest, unsigned char *src)
- /* -> dest, src. Concatenates src to the end of dest
- <- returns the resulting string and changes dest.
- */
- { long sLen = MIN(*src, 255 - *dest);
-
- BlockMove(src + 1, dest + *dest + 1, sLen);
- *dest += sLen;
- }
-
- void pStrcpy(unsigned char *dest, unsigned char *src)
- /* -> dest, src. Copies src into dest
- <- returns the resulting string and changes dest.
- */
- {
- BlockMove(src, dest, (long) *src + 1);
- }
-
- void ClearPointer(Ptr p,short s)
- /* -> p is a pointer and s is the number of bytes to clear out.
- <- returns nothing.
- */
- {
- while (s--)
- *p = 0, ++p;
- }
-
- Boolean CheckError(OSErr theError, OSErr exceptErr, short errIndex )
- /* -> theError, exceptErr. theError that has occures. Get the appropriate info
- for this error and report on it. exceptErr is the exception to the error
- that we will allow
- <- Boolean. If the noErr or exceptErr is true then this procedure will return TRUE, else
- the proc will return false.
- */
- { char *str, *str2;
- short itemHit;
-
- if ((theError == exceptErr) || (theError == noErr))
- return TRUE;
- GetIndString (str, kStrErr, errIndex);
- NumToString((long)theError, str2);
- ParamText(str, str2, nullStr, nullStr);
- itemHit = Alert(kDialID, NIL);
- return FALSE;
- }
-
- Ptr FindInitData()
- /* This routine is provided by CE Software. It was published in Inside QuicKeys™ 1.0
- copyright ©1987-88 CE Software. All rights reserved. QuicKeys™ is a trademark of CE Software.
- This routine will search the System Zone for a nonrelocatable block that contains a
- 0xA89F1234 (_Debugger, 0x1234) as the first long word of the block, and kOurCreat, ('flip') as the next one
- in the block. If it matches, then a pointerto some data is returned. (i.e. the pointer to our global data)
- This allows us to make changes, such as activation key, to our INIT from the cdev without
- having to restart the machine all the time. Much more convenient!!
- */
- {
- asm{
- move.l SysZone,A1 ;point A1 at the header
- lea OFFSET(Zone,heapData)(A1),A0 ;point A0 at the first block
- @0 cmp.l OFFSET(Zone,bkLim)(A1),A0 ;are we done?
- bge.s @998
- move.b (A0),D0 ;see if it's nonrelocatable
- andi.w #0xC0,D0
- cmp.w #0x40,D0
- bne.s @800 ;if not, next block
- move.l 8(A0),D0
- cmp.l #0xA89F1234,D0
- bne.s @800
- move.l 12(A0),D0
- cmp.l #kOurCreat,D0
- bne.s @800
- move.l 16(A0), D0 ;return the pointer to the global data
- bra.s @999
- @800
- move.l (A0),D0 ;point A3 to the next block
- andi.l #0xFFFFFF,D0 ;strip of header
- add.l D0,A0 ;add to A3
- bra.s @0 ;and loop back!
- @998
- clr.l D0 ;search failed, so return false
- @999
- }
- }